<template>
  <div class="ele-upload-video">
    <!-- 上传组件 -->
    <el-upload
      v-if="!value"
      :accept="accept"
      action="http://10.10.82.34:8100/admin/file/upload"
      :before-upload="handleBeforeUploadVideo"
      :disabled="
        isLoading || (videoUploadPercent > 0 && videoUploadPercent < 100)
      "
      :headers="headers"
      :name="name"
      :on-error="handleUploadError"
      :on-progress="handleUploadProcess"
      :on-success="handleUploadSuccess"
      :show-file-list="false"
      :with-credentials="withCredentials"
      :http-request="httpRequest"
      drag
    >
      <!-- 上传进度 -->
      <el-progress
        v-if="videoUploadPercent > 0"
        :percentage="videoUploadPercent"
        style="margin-top: 20px;"
        type="circle"
      />
      <div
        v-else-if="isLoading"
        v-loading="isLoading"
        class="loading-pannel"
        element-loading-text="视频上传中，请耐心等待"
      />
      <!-- 上传提示 -->
      <template v-else>
        <i class="el-icon-upload" />
        <div class="el-upload__text">
          将视频拖到此处，或
          <em>点击上传</em>
        </div>
        <div v-if="showTip" slot="tip" class="el-upload__tip">
          请上传
          <span
            style="color: #f56c6c;"
          >&nbsp;{{ fileType ? fileType.join('/') : '视频' }}&nbsp;</span>格式文件
          <template v-if="fileSize">
            ，且文件大小不超过
            <span style="color: #f56c6c;">{{ fileSize }}</span>&nbsp;MB
          </template>
        </div>
      </template>
    </el-upload>

    <!-- 视频缩略 -->
    <vue-hover-mask v-if="value">
      <video
        :autoplay="false"
        :src="value"
        :style="{
          width: width + 'px',
          height: height ? height + 'px' : 'auto'
        }"
      >
        您的浏览器不支持视频播放
      </video>
      <template v-slot:action>
        <span class="ele-upload-video_mask__item" @click="handlePlayerVideo">
          <i class="el-icon-zoom-in" />
        </span>
        <span class="ele-upload-video_mask__item" @click="handleRemove">
          <i class="el-icon-delete" />
        </span>
      </template>
    </vue-hover-mask>

    <!-- 弹窗播放 -->
    <el-dialog :visible.sync="isShowVideo" append-to-body>
      <video
        v-if="true"
        :autoplay="true"
        src="https://vd2.bdstatic.com/mda-mfv7kvuw5sstktd6/sc/cae_h264_clips/1625031009779544888/mda-mfv7kvuw5sstktd6.mp4?auth_key=1625060534-0-0-c577070283f4247b590d48c3d85d70a7&bcevod_channel=searchbox_feed&pd=1&pt=3&abtest=3000165_1"
        controls="controls"
        style="width: 100%;"
      >
        您的浏览器不支持视频播放
      </video>
    </el-dialog>
  </div>
</template>

<script>
import VueHoverMask from 'vue-hover-mask'
import { upload } from 'dependencies/api/index'
import SectionLoadingMixin from 'modules/mixins/section-loading'
const createFileUrl = file => {
  return (window.URL || window.webkitURL).createObjectURL(file)
}
export default {
  name: 'VideoUpload',
  components: {
    VueHoverMask
  },
  mixins: [SectionLoadingMixin],
  props: {
    // 值
    value: {
      type: String,
      default: ''
    },
    // 上传地址
    action: {
      type: String,
      default: 'http://10.10.82.34:8100/admin/file/upload'
    },
    // 文件大小限制(Mb)
    fileSize: {
      type: Number,
      default: undefined
    },
    // 显示宽度(px)
    width: {
      type: Number,
      default: 360
    },
    // 显示高度(默认auto)
    height: {
      type: Number,
      default: undefined
    },
    videoHeight: {
      type: Number,
      default: undefined
    },
    videoWidth: {
      type: Number,
      default: undefined
    },
    // 是否显示提示
    isShowTip: {
      type: Boolean,
      default: true
    },
    // 是否显示上传成功的提示
    isShowSuccessTip: {
      type: Boolean,
      default: true
    },
    // 文件类型
    fileType: {
      type: Array,
      default() {
        return []
      }
    },
    // 设置上传的请求头部(同官网)
    headers: {
      type: Object,
      default() {
        return {}
      }
    },
    // 支持发送 cookie 凭证信息 (同官网)
    withCredentials: {
      type: Boolean,
      default: false
    },
    // 上传的文件字段名 (同官网)
    name: {
      type: String,
      default: 'file'
    },
    // 覆盖默认的上传行为，可以自定义上传的实现 (同官网)
    // httpRequest: {
    //   type: Function,
    //   default() {
    //     return () => {}
    //   }
    // },
    // 接受上传的文件类型（thumbnail-mode 模式下此参数无效）(同官网)
    accept: {
      type: String,
      default: ''
    },
    // 删除前的操作(同官网)
    beforeRemove: {
      type: Function,
      default() {
        return () => {}
      }
    }
  },
  data() {
    return {
      isShowVideo: false,
      videoUploadPercent: 0
    }
  },
  computed: {
    // 是否显示提示
    showTip() {
      return this.isShowTip && (this.fileType || this.fileSize)
    }
  },
  methods: {
    // 上传大小和格式检测
    async handleBeforeUploadVideo(file) {
      // 校检格式
      let isVideo = false
      const sizeLimit = await this.validateVideoSize(file)
      if (!sizeLimit) {
        return Promise.reject()
      }
      if (Array.isArray(this.fileType)) {
        const type = file.type.split('/')
        isVideo = type[0] === 'video' && this.fileType.includes(type[1])
      } else {
        isVideo = file.type.includes('video')
      }
      if (!isVideo) {
        this.$message.error(`${file.name}格式不正确, 请上传格式正确的视频`)
        return Promise.reject()
      }
      // 校检文件大小
      if (this.fileSize) {
        const isLt = file.size / 1024 / 1024 < this.fileSize
        if (!isLt) {
          this.$message.error(`上传视频大小不能超过${this.fileSize}MB!`)
          return Promise.reject()
        }
      }
      return true
    },
    validateVideoSize(file) {
      const video = document.createElement('video')
      video.setAttribute('width', '10')
      video.setAttribute('height', '10')
      video.setAttribute('controls', 'controls')
      video.setAttribute('src', createFileUrl(file))
      document.body.appendChild(video)
      const that = this
      return new Promise((resolve, reject) => {
        video.addEventListener('canplay', function(e) {
          if (that.videoWidth || that.videoHeight) {
            // that.fileList[that.fileList.length - 1].width = e.target.videoWidth
            // that.fileList[that.fileList.length - 1].height = e.target.videoHeight
            // console.log('视频宽高：', that.fileList[that.fileList.length - 1])
          }
          const valid =
            !that.videoWidth || !that.videoHeight
              ? true
              : e.target.videoWidth === that.videoWidth &&
                e.target.videoHeight === that.videoHeight

          console.log(
            valid,
            e.target.videoWidth,
            e.target.videoHeight,
            that.videoWidth,
            that.videoHeight
          )
          document.body.removeChild(video)
          valid ? resolve() : reject('SIZE_ERR')
        })
      }).then(
        () => {
          return true
        },
        err => {
          if (err === 'SIZE_ERR') {
            this.$message.error(
              `视频尺寸限制为${this.videoWidth} x ${this.videoHeight}!`
            )
          }
          return false
        }
      )
    },
    // 上传进度
    handleUploadProcess(event, file) {
      this.videoUploadPercent = Number(file.percentage.toFixed(0))
    },
    // 上传成功
    handleUploadSuccess(response, file) {
      this.videoUploadPercent = 0
      if (this.isShowSuccessTip) {
        this.$message.success('上传成功!')
      }
      // if (this.responseFn) {
      //   this.$emit('input', this.responseFn(response, file))
      // }
      this.$emit('input', response.data)
    },
    // 上传失败
    handleUploadError(err, file, fileList) {
      this.$message.error('上传失败, 请重试!')
      this.videoUploadPercent = 0
      this.$emit('error', err, file, fileList)
    },
    // 删除视频
    doRemove() {
      this.$emit('delete')
      this.$emit('input', null)
    },
    handleRemove() {
      if (!this.beforeRemove) {
        this.doRemove()
      } else if (typeof this.beforeRemove === 'function') {
        const before = this.beforeRemove(this.value)
        if (before && before.then) {
          before.then(
            () => {
              this.doRemove()
            },
            () => {}
          )
        } else if (before !== false) {
          this.doRemove()
        }
      }
    },
    // 播放视频
    handlePlayerVideo() {
      this.isShowVideo = true
    },
    async httpRequest(data) {
      const file = new FormData()
      file.append('file', data.file)
      this.loading()
      const res = await upload(file)
      this.loaded()
      if (res.success) {
        return res
      } else {
        this.handleUploadError()
      }
    }
  }
}
</script>

<style>
.ele-upload-video_mask__item {
  padding: 0 10px;
}
.ele-upload-video .el-upload__tip {
  line-height: 12px;
}
.ele-upload-video .loading-pannel {
  width: 100%;
  height: 100%;
}
</style>
